﻿using System;
using System.Collections.Generic;

using Moe.ECamel.Common.Contracts;
using Moe.ECamel.Common.Entities;
using Moe.ECamel.Common.Security;
using Moe.ECamel.Common.Utils;
using Moe.ECamel.Client.ServiceProxies;

namespace Moe.ECamel.Client.Controllers
{
	public class ItemsController : EntityController<Item, SearchItemResult>
	{
		public readonly SearchItemsRequest SearchRequest;
		private readonly int? _customerId;

		public ItemsController()
			:base()
		{
			this.SearchRequest = InitSearchRequest(null);			
		}
		public ItemsController(int libraryId)
			: base(libraryId)
		{
			this.SearchRequest = InitSearchRequest(libraryId);
		}
		public ItemsController(Customer customer)
			: base(customer.LibraryId)
		{
			this.SearchRequest = InitSearchRequest(customer.LibraryId);
			this._customerId = customer.CustomerId;
		}

		private static SearchItemsRequest InitSearchRequest(int? libraryId)
		{
			var searchRequest = new SearchItemsRequest();
			searchRequest.LibraryId = libraryId;
			searchRequest.Template = new Item { ItemTypeId = 1, Title = "", CatalogNumber = "" };
			return searchRequest;
		}

		public override Item NewEntity()
		{
			var item = base.NewEntity();
			item.ItemTypeId = 1;
			return item;
		}

		public override ECamelError Create(Item entity)
		{
			using (var serviceProxy = new ItemServiceProxy())
			{
				return serviceProxy.CreateItem(entity);
			}
		}

		public override ECamelError Update(Item entity)
		{
			using (var serviceProxy = new ItemServiceProxy())
			{
				return serviceProxy.UpdateItem(entity);
			}
		}

		protected override IList<SearchItemResult> LoadList()
		{
			using (var serviceProxy = new ItemServiceProxy())
			{
				return serviceProxy.SearchItems(this.SearchRequest).Items;
			}
		}

		public void AddCopy(Item item)
		{
			using (var serviceProxy = new InventoryServiceProxy())
			{
				serviceProxy.AddCopy(item.ItemId, ParentEntityId);
			}
		}
		public void DeleteCopy(Item item)
		{
			using (var serviceProxy = new InventoryServiceProxy())
			{
				serviceProxy.DeleteCopy(item.ItemId, ParentEntityId);
			}
		}
		public TransferCopyResponse TransferCopy(Item item)
		{
			using (var serviceProxy = new InventoryServiceProxy())
			{
				return serviceProxy.TransferCopy(item.ItemId, ParentEntityId);
			}
		}

		public bool RentPermitted
		{
			get { return _customerId.HasValue && ECamelHelper.IsPermitted(Operations.RentalRent); }
		}
		public bool AddItemPermitted
		{
			get { return ECamelHelper.IsPermitted(Operations.ItemAdd); }
		}
		public bool EditItemPermitted
		{
			get { return ECamelHelper.IsPermitted(Operations.ItemEdit); }
		}
		public bool AddInventoryPermitted
		{
			get { return ECamelHelper.IsPermitted(Operations.InventoryAdd); }
		}
		public bool RemoveInventoryPermitted
		{
			get { return ECamelHelper.IsPermitted(Operations.InventoryDelete); }
		}
		public bool TransferInventoryPermitted
		{
			get { return ECamelHelper.IsPermitted(Operations.InventoryTransfer); }
		}

		public RentalResponse RentItem(Item item)
		{
			var request = new RentalRequest(_customerId.Value, item.ItemId, SystemContainer.Clock.Today);
			using (var serviceProxy = new RentalServiceProxy())
			{
				return serviceProxy.RentItem(request);
			}
		}

		public ECamelError RequestNewCopy(Item item)
		{
			using (var serviceProxy = new InventoryServiceProxy())
			{
				return serviceProxy.RequestNewCopy(item.ItemId, this.ParentEntityId, SystemContainer.Clock.Today);
			}
		}

		public void AddItemReservation(Item item)
		{
			using (var serviceProxy = new ItemReservationServiceProxy())
			{
				serviceProxy.AddItemReservation(item.ItemId, _customerId.Value, SystemContainer.Clock.Today);
			}
		}

		public Customer GetCustomer()
		{
			using (var serviceProxy = new CustomerServiceProxy())
			{
				return serviceProxy.GetCustomerById(_customerId.Value);
			}
		}
	}
}